package com.songhq.javanio;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;

/**
 * java原生的nio
 * 
 * 
 * 业务上还是阻塞的。只不过连接不阻塞，及相当于一个线程可以处理多个连接，相当于处理一个连接的读操作，本次的读操作完成后，即可进行别的连接的读操作
 * 
 * 
 * 
 * 
 * 
 * @author Administrator
 *
 */
public class JavaNioServer {

	public static void main(String[] args) throws IOException {

		// 1.打开ServerSocketChannel，用于监听客户端的连接，它是所有连接的父管道
		ServerSocketChannel acceptorSvr = ServerSocketChannel.open();
		// 2.绑定监听端口，设置连接为非阻塞模式
		acceptorSvr.socket().bind(new InetSocketAddress(8080));
		acceptorSvr.configureBlocking(false);
		//事件驱动api
		Selector selector = Selector.open();
		// 4.将ServerSocketChannel注册到Rector线程的多路复用器Selector上，监听Accept事件
		acceptorSvr.register(selector, SelectionKey.OP_ACCEPT);

		System.out.println("服务端开始工作：");

		// 创建消息处理器
		ServerHandlerBs handler = new ServerHandlerImpl(1024);

		while (true) {
			selector.select();  //这个是阻塞的，相当于不停的捕捉事件，即消息
			System.out.println("开始处理请求 ： ");
			// 获取selectionKeys并处理
			Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
			while (keyIterator.hasNext()) {
				SelectionKey key = keyIterator.next();
				try {
					// 连接请求
					if (key.isAcceptable()) {
						handler.handleAccept(key);
					}
					// 读请求
					if (key.isReadable()) {
						System.out.println(handler.handleRead(key));
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				// 处理完后移除当前使用的key
				keyIterator.remove();
			}
			System.out.println("完成请求处理。");
		}
	}
}
